/**
 * 数字加减
 */
var compBase = require("mlib/comp/base");
var parseModule = require("mlib/dom/parseModule");

var merge = require("mlib/json/merge");
var closest = require("mlib/dom/closest");
var siblings = require("mlib/dom/siblings");
var touch = require("mlib/evt/touch");


var that = compBase();	

var me = null;
var target = null;
var parentElement = null;
var numbtn = null;
var attrs = null;
var m_quantitys = null;
var rules = {
		"defaults": { "min": null, "max": null, "step": 1,      "precision": 0 },
		"currency": { "min": 0.00, "max": null, "step": 0.01,   "precision": 2 },
		"quantity": { "min": 1,    "max": 999,  "step": 1,      "precision": 0 },
		"percent":  { "min": 1,    "max": 100,  "step": 1,      "precision": 0 },
		"month":    { "min": 1,    "max": 12,   "step": 1,      "precision": 0 },
		"day":      { "min": 1,    "max": 31,   "step": 1,      "precision": 0 },
		"hour":     { "min": 0,    "max": 23,   "step": 1,      "precision": 0 },
		"minute":   { "min": 1,    "max": 59,   "step": 1,      "precision": 0 },
		"second":   { "min": 1,    "max": 59,   "step": 1,      "precision": 0 }
	};
	
 module.exports = function integration(node,opt) {
    return new Spinning(node,opt)
}

function Spinning(node, opt) {		
	if(node == undefined){
		return;
	}
 
    me = this;   
	opt = opt||{};
	opt = merge({	
        "btncls":".num-btn",	
        "initEvent":true,	
        "inputcls":".quantity",	
        "pluscls":".decrement",	
        "lesscls":".increment",	
		"rule":"quantity",
		"reset":false,
	},opt);
	this.options = 	merge(rules[opt.rule],opt);

	numbtn = this.options.btncls;
	if(this.options.initEvent){
		this.updateDisabled(node);
	}
	touch.on(node, "tap", numbtn, function(ev) {
		target = closest(ev.target,numbtn);  
		parentElement = target.parentElement;	
		me.options.nodeList = parseModule(parentElement);
		me.input = me.options.nodeList.quantity;
		attrs = me.input.dataset;
		me.min = attrs.min || Number(me.options.min) || 0;
		me.max = attrs.max || Number(me.options.max) || 0;	
		if(parseInt(me.max)==0){me.max=999;}
		//debugger
		if(target.classList.contains("disabled")){
			if(me.options.reset && parseInt(me.input.value)<=me.min){
				me.input.value = "0";
				that.fire("inputChange", {
					"input":me.input,
					"dir":-1
				});
			}
			return;
		}
		me.spin(target.dataset.spin);
	});
	
	return that;
	
}
Spinning.prototype.spin = function(dir) {
	if (this.input.getAttribute('disabled')) {
		return;
	}
	this.oldValue = this.value();
	var step = Object.prototype.toString.call(this.options.step) == "[object Function]" ? this.options.step.call(this, dir) : this.options.step;
	var multipler = dir === 'up' ? 1 : -1;
	this.value(this.oldValue + Number(step) * multipler,multipler);
};
Spinning.prototype.value = function(v,dir) {
	if (v === null || v === undefined) {
		return this.numeric(this.input.value);
	}
	v = this.numeric(v);
	var valid = this.validate(v);
	if (valid !== 0) {
		v = (valid === -1) ? this.min : this.max;
	}
	this.input.value=new Number(v).toFixed(this.options.precision);

	if (this.oldValue !== this.value()) {
		this.inputDisable();
		that.fire("inputChange", {
			"input":this.input,
			"dir":dir
		});
	}
};
Spinning.prototype.inputDisable = function(){
	var nodeList = this.options.nodeList;
	
	parseInt(this.input.value)<=this.min ? nodeList.down.classList.add("disabled") : nodeList.down.classList.remove("disabled");
	parseInt(this.input.value)>=this.max ? nodeList.up.classList.add("disabled") : nodeList.up.classList.remove("disabled");
}
Spinning.prototype.numeric = function(v) {
	v = this.options.precision > 0 ? parseFloat(v, 10) : parseInt(v, 10);
	// If the variable is a number
	if (isFinite(v)) {
		return v;
	}
	return v || this.options.min || 0;
};
Spinning.prototype.validate = function(val) {
	if (this.min !== null && val < this.min) {
		return -1;
	}
	if (this.max !== null && val > this.max) {
		return 1;
	}
	return 0;
};
Spinning.prototype.updateDisabled = function(node){
	var opts = this.options;
	m_quantitys = [].slice.call(node.querySelectorAll(opts.inputcls));
	m_quantitys.forEach(function(item,index){
		var plusel = siblings(item, opts.pluscls)[0];
		var lessel = siblings(item, opts.lesscls)[0];
		lessel && (parseInt(item.value)<=item.dataset.min ? lessel.classList.add("disabled") : lessel.classList.remove("disabled")) ;
		(plusel&&item.dataset.max>0) && (parseInt(item.value)>=item.dataset.max ? plusel.classList.add("disabled") : plusel.classList.remove("disabled")) ;
	});
};
 